package com.xinzhidi.web.custommodel.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinzhidi.common.constant.AgreementConstants;
import com.xinzhidi.common.core.domain.model.LoginUser;
import com.xinzhidi.common.core.page.TableDataInfo;
import com.xinzhidi.common.exception.ServiceException;
import com.xinzhidi.common.utils.DateUtils;
import com.xinzhidi.common.utils.SecurityUtils;
import com.xinzhidi.common.utils.StringUtils;
import com.xinzhidi.common.utils.bean.BeanUtils;
import com.xinzhidi.web.build.domain.BuildUnit;
import com.xinzhidi.web.build.domain.CBuild;
import com.xinzhidi.web.build.mapper.BuildUnitMapper;
import com.xinzhidi.web.build.mapper.CBuildMapper;
import com.xinzhidi.web.custommodel.domain.CustomModel;
import com.xinzhidi.web.custommodel.dto.CustomModelAddDto;
import com.xinzhidi.web.custommodel.dto.CustomModelBatchAddDto;
import com.xinzhidi.web.custommodel.dto.CustomModelListDto;
import com.xinzhidi.web.custommodel.dto.CustomModelUpdDto;
import com.xinzhidi.web.custommodel.mapper.CustomModelMapper;
import com.xinzhidi.web.custommodel.vo.CustomModelInfoVo;
import com.xinzhidi.web.custommodel.vo.CustomModelListVo;
import com.xinzhidi.web.equipment.domain.Equipment;
import com.xinzhidi.web.house.domain.Household;
import com.xinzhidi.web.house.mapper.HouseholdMapper;
import com.xinzhidi.web.plot.domain.entity.CPlot;
import com.xinzhidi.web.plot.domain.vo.SelectVo;
import com.xinzhidi.web.plot.mapper.CPlotMapper;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 自定义模型Service业务层处理
 *
 * @author cx
 * @date 2023-06-15
 */
@Service
public class CustomModelService extends ServiceImpl<CustomModelMapper, CustomModel> {
    @Autowired
    private CustomModelMapper customModelMapper;

    @Autowired
    private CPlotMapper cPlotMapper;

    @Autowired
    private CBuildMapper cBuildMapper;

    @Autowired
    private BuildUnitMapper buildUnitMapper;

    @Autowired
    private HouseholdMapper householdMapper;

    /**
     * 查询自定义模型
     *
     * @param id 自定义模型主键
     * @return 自定义模型
     */
    public CustomModelInfoVo selectCustomModelById(Long id) {
        CustomModel customModel = customModelMapper.selectById(id);
        CustomModelInfoVo infoVo = new CustomModelInfoVo();
        BeanUtils.copyProperties(customModel, infoVo);
        return infoVo;
    }

    /**
     * 查询自定义模型列表
     *
     * @param dto 查询自定义模型dto
     * @return 自定义模型
     */
    public TableDataInfo<CustomModelListVo> selectCustomModelList(CustomModelListDto dto) {
        LambdaQueryWrapper<CustomModel> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(dto.getParentId() != null, CustomModel::getParentId, dto.getParentId());
        wrapper.like(StringUtils.isNotEmpty(dto.getModelName()), CustomModel::getModelName, dto.getModelName());
        wrapper.eq(StringUtils.isNotEmpty(dto.getModelLevel()), CustomModel::getModelLevel, dto.getModelLevel());
        wrapper.eq(StringUtils.isNotEmpty(dto.getHouseType()), CustomModel::getHouseType, dto.getHouseType());
        wrapper.eq(StringUtils.isNotEmpty(dto.getModelType()), CustomModel::getModelType, dto.getModelType());
        wrapper.ge(StringUtils.isNotEmpty(dto.getStartTime()), CustomModel::getCreateTime, dto.getStartTime());
        wrapper.le(StringUtils.isNotEmpty(dto.getEndTime()), CustomModel::getCreateTime, dto.getEndTime());

        wrapper.eq(StringUtils.isNotEmpty(dto.getRadiatorType()), CustomModel::getRadiatorType, dto.getRadiatorType());
        wrapper.eq(dto.getResidentAreaStart() != null, CustomModel::getResidentAreaStart, dto.getResidentAreaStart());
        wrapper.eq(dto.getResidentAreaEnd() != null, CustomModel::getResidentAreaEnd, dto.getResidentAreaEnd());
        wrapper.eq(StringUtils.isNotEmpty(dto.getStatus()), CustomModel::getStatus, dto.getStatus());
        wrapper.like(StringUtils.isNotEmpty(dto.getArithmeticName()), CustomModel::getArithmeticName, dto.getArithmeticName());
        wrapper.eq(dto.getUseQuantity() != null, CustomModel::getUseQuantity, dto.getUseQuantity());
        wrapper.orderByDesc(CustomModel::getId);
        List<CustomModel> list = customModelMapper.selectList(wrapper);
        return TableDataInfo.getDataTable(list, (domain -> {
            CustomModelListVo vo = new CustomModelListVo();
            //获取模型使用数量
            String id = "," + domain.getId() + ",";
            Integer useQuantity = customModelMapper.getUseQuantity(id);
            vo.setUseQuantity(useQuantity);
            BeanUtils.copyProperties(domain, vo);
            //获取子模型数量
            Integer childQuantity = customModelMapper.getChildQuantity(domain.getId());
            vo.setChildCount(childQuantity);
            return vo;
        }));
    }

    /**
     * 查询自定义模型列表
     *
     * @param dto 查询自定义模型dto
     * @return 自定义模型
     */
    public TableDataInfo<SelectVo> listCustomModelSelect(CustomModelListDto dto) {
        LambdaQueryWrapper<CustomModel> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(dto.getModelName()), CustomModel::getModelName, dto.getModelName());
        wrapper.eq(StringUtils.isNotEmpty(dto.getModelLevel()), CustomModel::getModelLevel, dto.getModelLevel());
        wrapper.eq(StringUtils.isNotEmpty(dto.getModelType()), CustomModel::getModelType, dto.getModelType());
        wrapper.eq(StringUtils.isNotEmpty(dto.getHouseType()), CustomModel::getHouseType, dto.getHouseType());
        wrapper.eq(StringUtils.isNotEmpty(dto.getRadiatorType()), CustomModel::getRadiatorType, dto.getRadiatorType());
        wrapper.eq(dto.getResidentAreaStart() != null, CustomModel::getResidentAreaStart, dto.getResidentAreaStart());
        wrapper.eq(CustomModel::getStatus, 1);
        wrapper.eq(dto.getResidentAreaEnd() != null, CustomModel::getResidentAreaEnd, dto.getResidentAreaEnd());
        wrapper.eq(StringUtils.isNotEmpty(dto.getStatus()), CustomModel::getStatus, dto.getStatus());
        wrapper.like(StringUtils.isNotEmpty(dto.getArithmeticName()), CustomModel::getArithmeticName, dto.getArithmeticName());
        wrapper.eq(dto.getUseQuantity() != null, CustomModel::getUseQuantity, dto.getUseQuantity());
        wrapper.orderByDesc(CustomModel::getId);

        return TableDataInfo.getDataTable(customModelMapper.selectList(wrapper), (domain -> {
            SelectVo vo = new SelectVo();
            vo.setLabel(domain.getModelName());
            vo.setValue(domain.getId().toString());
            return vo;
        }));
    }

    /**
     * 新增自定义模型
     *
     * @param dto 新增自定义模型dto
     * @return 结果
     */
    public int insertCustomModel(CustomModelAddDto dto) {
        if (!CollectionUtils.isEmpty(list(new LambdaQueryWrapper<CustomModel>().eq(CustomModel::getModelName, dto.getModelName())))) {
            throw new ServiceException("模型名称重复，请重新添加！");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();

        CustomModel customModel = new CustomModel();
        BeanUtils.copyProperties(dto, customModel);
        customModel.setCreateBy(loginUser.getUserId().toString());
        customModel.setCreateTime(DateUtils.getNowDate());
        return customModelMapper.insert(customModel);
    }

    /**
     * 修改自定义模型
     *
     * @param dto 修改自定义模型dto
     * @return 结果
     */
    public int updateCustomModel(CustomModelUpdDto dto) {
        if (!CollectionUtils.isEmpty(list(new LambdaQueryWrapper<CustomModel>()
                .eq(CustomModel::getModelName, dto.getModelName()).ne(CustomModel::getId, dto.getId())))) {
            throw new ServiceException("模型名称重复，请重新添加！");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();

        CustomModel customModel = new CustomModel();
        BeanUtils.copyProperties(dto, customModel);
        customModel.setUpdateBy(loginUser.getUserId().toString());
        customModel.setUpdateTime(DateUtils.getNowDate());
        return customModelMapper.updateById(customModel);
    }

    /**
     * 批量删除自定义模型
     *
     * @param ids 需要删除的自定义模型主键
     * @return 结果
     */
    public int deleteCustomModelByIds(Long[] ids) {
        for (Long id : ids) {
            checkBindModel(id);
        }
        return customModelMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除自定义模型信息
     *
     * @param id 自定义模型主键
     * @return 结果
     */
    public int deleteCustomModelById(Long id) {
        checkBindModel(id);
        return customModelMapper.deleteById(id);
    }

    public void checkBindModel(Long id){
        String tableName = "c_plot";
        List<CPlot> PlotListVo = customModelMapper.checkBindModel(id, tableName);
        if (!CollectionUtils.isEmpty(PlotListVo)){
            throw new ServiceException("该模型已经被绑定，不能删除！");
        }
        tableName = "c_build";
        List<CBuild> cBuilds = customModelMapper.checkBindModel(id, tableName);
        if (!CollectionUtils.isEmpty(cBuilds)){
            throw new ServiceException("该模型已经被绑定，不能删除！");
        }
        tableName = "build_unit";
        List<BuildUnit> buildUnits = customModelMapper.checkBindModel(id, tableName);
        if (!CollectionUtils.isEmpty(buildUnits)){
            throw new ServiceException("该模型已经被绑定，不能删除！");
        }
        tableName = "c_household";
        List<Household> households = customModelMapper.checkBindModel(id, tableName);
        if (!CollectionUtils.isEmpty(households)){
            throw new ServiceException("该模型已经被绑定，不能删除！");
        }
    }


    /**
     * 根据id集合查询模型数据
     *
     * @param ids id集合，逗号分隔
     * @return
     */
    public List<CustomModel> getModelByIds(String ids) {
        if (StringUtils.isBlank(ids)){
            return Lists.newArrayList();
        }
        List longIds = Arrays.asList(ids.split(","));
        if(CollectionUtils.isEmpty(longIds)){
            return Lists.newArrayList();
        }
        LambdaQueryWrapper<CustomModel> wrapper = Wrappers.lambdaQuery();
        wrapper.in(CustomModel::getId, Arrays.asList(ids.split(",")));
        return customModelMapper.selectList(wrapper);

    }


    /**
     * 批量绑定模型
     *
     * @return
     */
    public int batchBindModel(CustomModelBatchAddDto dto) {
        String type = dto.getType();
        if (StringUtils.isEmpty(type)) {
            throw new ServiceException("业务类型不能为空");
        }
        if (CollectionUtils.isEmpty(dto.getIds())) {
            throw new ServiceException("业务主键id集合不能为空");
        }
        String tableName = "c_plot";
        if ("1".equals(type)) {
            tableName = "c_build";
        } else if ("2".equals(type)) {
            tableName = "build_unit";
        } else if ("3".equals(type)) {
            tableName = "c_household";
        }
        dto.setTableName(tableName);
        return customModelMapper.batchBindModel(dto);
    }

    /**
     *
     * 通过设备查找对应级别（单元、住户：目前只有这2种级别才有设备）的模型id集合
     * @author cx
     * @date 2023/8/8 8:20
     * @param equipment 设备
     * @return java.util.List<java.lang.Integer>
     **/
    public List<Integer> getModelIdsByEquipment(Equipment equipment) {
        List<Integer> ids = Lists.newArrayList();
        String equipmentLevel = equipment.getEquipmentLevel();
        if(equipmentLevel.equals(AgreementConstants.DataType.BUILD_UNIT)){
            //单元
            Long unitId = equipment.getUnitId();
            BuildUnit buildUnit = buildUnitMapper.selectById(unitId);
            String modelIds = buildUnit.getModelIds();
            if(StringUtils.isNotEmpty(modelIds)){
                ids = Arrays.stream(modelIds.split(",")).map(Integer::parseInt).collect(Collectors.toList());
            }
            return ids;
        }
        if(equipmentLevel.equals(AgreementConstants.DataType.HOUSEHOLD)){
            //住户
            Long householdId = equipment.getHouseholdId();
            Household household = householdMapper.selectById(householdId);
            String modelIds = household.getModelIds();
            if(StringUtils.isNotEmpty(modelIds)){
                ids = Arrays.stream(modelIds.split(",")).filter(x -> org.apache.commons.lang3.StringUtils.isNotBlank(x)).map(Integer::parseInt).collect(Collectors.toList());
            }
            return ids;
        }
        return ids;
    }

}
